package com.wzx.data.utils;

import com.alibaba.fastjson2.JSON;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.Headers;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpMethodName;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.*;
import com.qcloud.cos.region.Region;
import com.wzx.basics.config.ConstantConfig;
import com.wzx.basics.exception.WzxException;
import com.wzx.data.entity.Setting;
import com.wzx.data.service.ISettingService;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.wzx.data.vo.OssSettingVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;

/**
 * 本地文件工具类
 * @author wzx
 */
@Component
public class FileUtils implements FileManage {

    @Autowired
    private ISettingService iSettingService;

    private static final String LOCAL_FILE_PATH_STEP = "/";

    /**
     * 创建COS客户端
     * @return
     */
    public static COSClient createCOSClient(){
        // 1 初始化用户身份信息(secretId, secretKey) 这里填你自己的
        COSCredentials cred = new BasicCOSCredentials(ConstantConfig.ACCESS_KEY_ID, ConstantConfig.ACCESS_KEY_SECRET);
        ClientConfig clientConfig = new ClientConfig(new Region(ConstantConfig.END_POINT));
        // 如果要获取 https 的 url 则在此设置，否则默认获取的是 http url
        clientConfig.setHttpProtocol(HttpProtocol.https);
        // 3 生成cos客户端
        COSClient cosclient = new COSClient(cred, clientConfig);
        return cosclient;
    }

    public static void view(String url, HttpServletResponse response) {
        File viewFile = new File(url);
        if (!viewFile.exists()) {
            throw new WzxException("没有文件");
        }
        try (FileInputStream is = new FileInputStream(viewFile); BufferedInputStream bis = new BufferedInputStream(is)) {
            OutputStream out = response.getOutputStream();
            byte[] buf = new byte[1024];
            int bytesRead;
            while ((bytesRead = bis.read(buf)) > 0) {
                out.write(buf, 0, bytesRead);
            }
        } catch (IOException e) {
            throw new WzxException("读取下载文件出错" + e);
        }
    }
    public static String download(String url){
        COSClient cosClient = createCOSClient();
        // 指定文件在 COS 上的路径，即对象键。例如对象键为 folder/picture.jpg，则表示下载的文件 picture.jpg 在 folder 路径下
        String[] files = url.split("ap-guangzhou.myqcloud.com/");
        String key = files[1];
        GeneratePresignedUrlRequest req =
                new GeneratePresignedUrlRequest(ConstantConfig.BUCKET_NAME, key, HttpMethodName.GET);
        // 填写本次请求的参数
        // 设定限速值，这里限速10M/s
        req.addRequestParameter("x-cos-traffic-limit", "8388608");
        req.addRequestParameter("response-content-disposition","attachment");
        // 填写本次请求的头部。Host 必填
        req.putCustomRequestHeader(Headers.HOST,
                cosClient.getClientConfig().getEndpointBuilder().buildGeneralApiEndpoint(ConstantConfig.BUCKET_NAME));
        URL down = cosClient.generatePresignedUrl(req);
        cosClient.shutdown();
        return down.toString();
    }
    @Override
    public String inputStreamUpload(InputStream inputStream, String key, MultipartFile file) {
        OssSettingVo os = getOssSetting();
        String day = DateUtil.format(DateUtil.date(), "yyyyMMdd");
        String path = os.getFilePath() + LOCAL_FILE_PATH_STEP + day;
        File dir = new File(path);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        File f = new File(path + LOCAL_FILE_PATH_STEP + key);
        if (f.exists()) {
            throw new WzxException("文件名称重复");
        }
        try {
            file.transferTo(f);
            return path + LOCAL_FILE_PATH_STEP + key;
        } catch (IOException e) {
            throw new WzxException("上传文件出错 " + e);
        }
    }

    @Override
    public String uploadFile(MultipartFile file,String type) {
        // 1 初始化用户身份信息（secretId, secretKey）。
        String secretId = ConstantConfig.ACCESS_KEY_ID;
        String secretKey = ConstantConfig.ACCESS_KEY_SECRET;
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        // 2 设置 bucket 的地域
        // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法
        Region region = new Region(ConstantConfig.END_POINT);
        ClientConfig clientConfig = new ClientConfig(region);
        // 设置使用 https 协议
        clientConfig.setHttpProtocol(HttpProtocol.https);
        // 3 生成 cos 客户端。
        COSClient cosClient = new COSClient(cred, clientConfig);
        //上传后返回的url
        String url = null;
        try {
            ObjectMetadata objectMetadata = new ObjectMetadata();
            // 指定要上传的文件
            InputStream inputStream = file.getInputStream();
            // 指定文件上传到 COS 上的路径，即对象键。例如对象键为folder/picture.jpg，则表示将文件 picture.jpg 上传到 folder 路径下
            String key = type+file.getOriginalFilename();
            PutObjectRequest putObjectRequest = new PutObjectRequest(ConstantConfig.BUCKET_NAME, key,inputStream,objectMetadata);
            PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
            url = "https://"+ConstantConfig.BUCKET_NAME+"."+"cos"+"."+ConstantConfig.END_POINT+".myqcloud.com"+"/"+key;
        } catch (Exception clientException) {
            clientException.printStackTrace();
        }
        return url;
    }

    /**
     * 根据url删除云端文件
     * @param url
     */
    @Override
    public void removeFile(String url) {
        //todo 根据url删除云端文件
    }

    @Override
    public void deleteFile(String url) {
        FileUtil.del(new File(url));
    }

    @Override
    public String copyFile(String url, String toKey) {
        File copyFile = new File(url);
        String newUrl = copyFile.getParentFile() + LOCAL_FILE_PATH_STEP + toKey;
        FileUtil.copy(copyFile, new File(newUrl), true);
        return newUrl;
    }

    @Override
    public String renameFile(String url, String toKey) {
        File renameFile = new File(url);
        FileUtil.rename(renameFile, toKey, false, true);
        return renameFile.getParentFile() + LOCAL_FILE_PATH_STEP + toKey;
    }

    @Override
    public OssSettingVo getOssSetting() {
        Setting s1 = iSettingService.getById("FILE_VIEW");
        Setting s2 = iSettingService.getById("FILE_HTTP");
        Setting s3 = iSettingService.getById("FILE_PATH");
        if(s1 == null || s1 == null || s1 == null) {
            return null;
        }
        return new OssSettingVo(s1.getValue(),s2.getValue(),s3.getValue());
    }

}
